#include "countui.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QSpacerItem>
#include <QFileDialog>
#include <QDateTime>
#include <QGroupBox>
#include <QScrollArea>

// 构造函数，初始化UI
CountUI::CountUI(QWidget *parent) : QWidget(parent)
{
    // 设置窗口属性
    setWindowTitle("文件夹统计");
    setMaximumSize(1200,400);
    setMinimumSize(600,200);

    // 创建UI控件
    pathLabel = new QLabel("请输入文件夹路径:", this);
    inputLineEdit = new QLineEdit(this);
    confirmButton = new QPushButton("确认", this);
    cancelButton = new QPushButton("取消", this);
    statusLabel = new QLabel("就绪", this); // 状态标签
    statusLabel->setAlignment(Qt::AlignCenter);

    // 按钮布局 - 水平布局
    QHBoxLayout *buttonLayout = new QHBoxLayout();
    buttonLayout->addStretch();  // 添加弹性空间
    buttonLayout->addWidget(confirmButton);
    buttonLayout->addWidget(cancelButton);
    buttonLayout->addStretch();

    // 主布局 - 垂直布局
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    mainLayout->addWidget(pathLabel);
    mainLayout->addWidget(inputLineEdit);
    mainLayout->addStretch();
    mainLayout->addWidget(statusLabel); // 添加状态标签
    mainLayout->addLayout(buttonLayout);

    // 设置布局边距和间距
    mainLayout->setContentsMargins(20, 20, 20, 20);
    mainLayout->setSpacing(20);

    // 连接信号和槽
    connect(confirmButton, &QPushButton::clicked, this, &CountUI::onConfirmClicked);
    connect(cancelButton, &QPushButton::clicked, this, &CountUI::onCancelClicked);
}

// 析构函数
CountUI::~CountUI()
{
    cleanupScanner();  // 清理扫描线程
}

// 清理扫描线程
void CountUI::cleanupScanner()
{
    if (m_scanner) {
        // 断开所有连接
        m_scanner->disconnect();

        // 如果线程正在运行，请求终止
        if (m_scanner->isRunning()) {
            m_scanner->quit();  // 请求退出
            m_scanner->wait(500); // 等待500ms

            // 如果仍在运行，强制终止
            if (m_scanner->isRunning()) {
                m_scanner->terminate();  // 强制终止
                m_scanner->wait();
            }
        }

        delete m_scanner;  // 删除对象
        m_scanner = nullptr;
    }
}

// 确认按钮点击处理
void CountUI::onConfirmClicked()
{
    // 如果已有扫描正在进行，则忽略新请求
    if (m_scanner && m_scanner->isRunning()) {
        QMessageBox::information(this, "提示", "当前已有扫描任务正在进行，请等待完成");
        return;
    }

    QString path = inputLineEdit->text();
    if (path.isEmpty()) {
        QMessageBox::warning(this, "错误", "请输入文件夹路径！");
        return;
    }

    // 更新状态标签
    statusLabel->setText("正在扫描...");
    statusLabel->setStyleSheet("color: blue;");

    // 清理之前的扫描器
    cleanupScanner();

    // 创建新的扫描器
    m_scanner = new DirectoryScanner(path);
    // 连接扫描完成信号
    connect(m_scanner, &DirectoryScanner::scanningFinished, this, &CountUI::onScanFinished);
    // 连接文件处理进度信号
    connect(m_scanner, &DirectoryScanner::filesProcessed, this, [this](int count) {
        // 使用lambda确保在主线程更新UI
        QMetaObject::invokeMethod(this, [this, count]() {
            statusLabel->setText(QString("已扫描文件: %1").arg(count));
            statusLabel->setStyleSheet("color: blue;");
        });
    });

    // 启动扫描线程
    m_scanner->start();
}

// 进度更新函数
void CountUI::onFilesProcessed(int count)
{
    statusLabel->setText(QString("已扫描文件: %1").arg(count));
    statusLabel->setStyleSheet("color: blue;");
}

// 扫描完成处理
void CountUI::onScanFinished()
{
    if (m_scanner) {
        // 获取统计结果
        DirectoryStats stats = m_scanner->getStats();
        // 显示图表和结果
        showChartAndResults(stats);

        // 更新状态标签
        statusLabel->setText(QString("扫描完成，共 %1 个文件").arg(stats.file_count));
        statusLabel->setStyleSheet("color: green;");
    }

    // 清理扫描器
    cleanupScanner();
}

// 取消按钮点击处理
void CountUI::onCancelClicked()
{
    if (m_scanner && m_scanner->isRunning()) {
        // 询问用户是否确认取消
        int ret = QMessageBox::question(this, "确认", "扫描正在进行，确定要取消吗？");
        if (ret == QMessageBox::Yes) {
            cleanupScanner();
            statusLabel->setText("已取消");
            statusLabel->setStyleSheet("color: red;");
        }
    } else {
        this->close();  // 如果没有扫描，直接关闭窗口
    }
}

// 创建饼图
QChartView* CountUI::createPieChart(const QMap<QString, int> &fileTypes)
{
    // 准备数据：取数量最多的4种文件类型，其余合并为"其他"
    QVector<QPair<QString, int>> sortedTypes;
    for (auto it = fileTypes.begin(); it != fileTypes.end(); ++it) {
        sortedTypes.append(qMakePair(it.key(), it.value()));
    }

    // 按数量从大到小排序
    std::sort(sortedTypes.begin(), sortedTypes.end(),
              [](const QPair<QString, int> &a, const QPair<QString, int> &b) {
                  return a.second > b.second;
              });

    QPieSeries *series = new QPieSeries();
    int otherCount = 0;

    // 添加前4种文件类型
    for (int i = 0; i < sortedTypes.size(); ++i) {
        if (i < 4) {
            series->append(QString(".%1 (%2)").arg(sortedTypes[i].first).arg(sortedTypes[i].second),
                           sortedTypes[i].second);
        } else {
            otherCount += sortedTypes[i].second;
        }
    }

    // 添加"其他"类别
    if (otherCount > 0) {
        series->append(QString("其他 (%1)").arg(otherCount), otherCount);
    }

    // 设置图表样式
    QChart *chart = new QChart();
    chart->addSeries(series);
    chart->setTitle("文件类型分布");
    chart->legend()->setAlignment(Qt::AlignRight);

    // 设置切片标签可见
    for (QPieSlice *slice : series->slices()) {
        slice->setLabelVisible();
        // slice->setLabelArmLengthFactor(0.1);
    }

    QChartView *chartView = new QChartView(chart);
    chartView->setRenderHint(QPainter::Antialiasing);  // 抗锯齿
    chartView->setMinimumSize(600, 400);

    return chartView;
}

// 显示图表和结果
void CountUI::showChartAndResults(const DirectoryStats &stats)
{
    // 创建结果对话框
    QDialog *resultDialog = new QDialog(this); // 设置父对象为主窗口
    resultDialog->setWindowTitle("统计结果");
    resultDialog->setMinimumSize(800, 600);
    resultDialog->setAttribute(Qt::WA_DeleteOnClose); // 关闭时自动删除

    QVBoxLayout *mainLayout = new QVBoxLayout(resultDialog);

    // 添加基本信息区域
    QGroupBox *infoBox = new QGroupBox("基本信息");
    QVBoxLayout *infoLayout = new QVBoxLayout;

    infoLayout->addWidget(new QLabel(QString("扫描路径: %1").arg(stats.name)));
    infoLayout->addWidget(new QLabel(QString("目录总数: %1").arg(stats.dir_count)));
    infoLayout->addWidget(new QLabel(QString("文件总数: %1").arg(stats.file_count)));
    infoLayout->addWidget(new QLabel(QString("源代码总行数: %1").arg(stats.total_lines)));

    infoBox->setLayout(infoLayout);
    mainLayout->addWidget(infoBox);

    // 添加饼图
    QChartView *chartView = createPieChart(stats.file_types);
    mainLayout->addWidget(chartView);

    // 添加详细文件类型统计区域
    QGroupBox *detailBox = new QGroupBox("详细文件类型统计");
    QVBoxLayout *detailLayout = new QVBoxLayout;

    // 对文件类型按数量排序
    QVector<QPair<QString, int>> sortedTypes;
    for (auto it = stats.file_types.begin(); it != stats.file_types.end(); ++it) {
        sortedTypes.append(qMakePair(it.key(), it.value()));
    }

    std::sort(sortedTypes.begin(), sortedTypes.end(),
              [](const QPair<QString, int> &a, const QPair<QString, int> &b) {
                  return a.second > b.second;
              });

    // 显示所有文件类型及其百分比
    for (const auto &type : sortedTypes) {
        double percentage = (double)type.second / stats.file_count * 100;
        detailLayout->addWidget(new QLabel(
            QString(".%1: %2 个 (%3%)").arg(type.first).arg(type.second).arg(percentage, 0, 'f', 1)));
    }

    // 添加保存按钮
    QPushButton *saveButton = new QPushButton("保存结果");
    connect(saveButton, &QPushButton::clicked, this, [stats, resultDialog, chartView]() {
        // 获取保存路径（不带扩展名）
        QString defaultFileName = QString("统计结果_%1")
                                      .arg(QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss"));
        QString savePath = QFileDialog::getSaveFileName(
            resultDialog, "保存统计结果", defaultFileName, "文本文件 (*.txt)");

        if (!savePath.isEmpty()) {
            // 保存文本结果
            QFile file(savePath);
            if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
                QTextStream stream(&file);
                stream << "========== 目录统计结果 ==========\n";
                stream << QString("扫描时间: %1\n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));
                stream << QString("扫描路径: %1\n\n").arg(stats.name);
                stream << QString("目录总数: %1\n").arg(stats.dir_count);
                stream << QString("文件总数: %2\n").arg(stats.file_count);
                stream << QString("源代码总行数: %3\n\n").arg(stats.total_lines);

                stream << "---------- 文件类型统计 ----------\n";
                for (auto it = stats.file_types.begin(); it != stats.file_types.end(); ++it) {
                    double percentage = (double)it.value() / stats.file_count * 100;
                    stream << QString(".%1: %2 个 (%3%)\n").arg(it.key()).arg(it.value()).arg(percentage, 0, 'f', 1);
                }

                file.close();

                // 保存图表为图片
                QString imagePath = savePath.left(savePath.lastIndexOf('.')) + ".png";
                QPixmap p = chartView->grab();
                if (p.save(imagePath, "PNG")) {
                    QMessageBox::information(resultDialog, "保存成功",
                                             QString("统计结果已保存到:\n%1\n图表已保存为:\n%2").arg(savePath).arg(imagePath));
                } else {
                    QMessageBox::information(resultDialog, "部分保存成功",
                                             QString("统计结果已保存到:\n%1\n但图表保存失败").arg(savePath));
                }
            } else {
                QMessageBox::critical(resultDialog, "保存失败", "无法保存文件");
            }
        }
    });

    detailBox->setLayout(detailLayout);

    // 添加滚动区域以支持大量文件类型的显示
    QScrollArea *scrollArea = new QScrollArea;
    scrollArea->setWidget(detailBox);
    scrollArea->setWidgetResizable(true);

    mainLayout->addWidget(scrollArea);
    mainLayout->addWidget(saveButton);

    // 显示对话框（非模态）
    resultDialog->show();

    // 移动对话框位置，避免遮挡主界面
    QPoint mainPos = this->pos();
    QSize mainSize = this->size();
    resultDialog->move(mainPos.x() + mainSize.width() + 20, mainPos.y());
}